package cn.qianxun.meta.word.replace;

import cn.hutool.core.util.ObjectUtil;
import cn.qianxun.meta.word.vo.GenerateChartVO;
import com.aspose.words.*;
import com.aspose.words.Shape;

import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;

/**
 * @Author fuzhilin
 * @Date 2021/11/30 0030 16:05
 * @Description
 */
public class BarPercentStackedChart implements IReplacingCallback {

    private String key;
    private GenerateChartVO chartVO;

    public BarPercentStackedChart(String key, GenerateChartVO chartVO) {
        this.key = key;
        this.chartVO = chartVO;
    }

    @Override
    public int replacing(ReplacingArgs e) throws Exception {
        //获取当前节点
        Node currentNode = e.getMatchNode();
        //节点拆分处理当前匹配字段
        splitRun(currentNode, e.getMatchOffset());
        //获取当前文档
        Document document = (Document) currentNode.getDocument();
        DocumentBuilder builder = new DocumentBuilder(document);
        //将光标移动到指定节点
        builder.moveTo(currentNode);
        // 统计图标题
        String[] title = chartVO.getTitle();
        String name = chartVO.getName();
        // 统计图类型(参考：ChartType)
        int chartType = chartVO.getChartType();
        // 统计图字段
        String[] categories = chartVO.getCategories();
        // 统计图字段数据（二维数组支持多折线）
        double[][] values = chartVO.getValues();

        //设置统计图宽和高
        double height = chartVO.getHeight();
        if (ObjectUtil.isNull(height)) {
            height = 415;
        }
        double width = chartVO.getWidth();
        if (ObjectUtil.isNull(width)) {
            width = 415;
        }
        Boolean dataPercent = chartVO.getDataPercent();
        Boolean coordinatePercent = chartVO.getCoordinatePercent();
        //插入
        addChart(builder, chartType, name, title, categories, values, height, width, dataPercent, coordinatePercent);

       /* // 创建一个百分比堆叠条形图
        Shape chartShape = builder.insertChart(ChartType.BAR_PERCENT_STACKED, 400, 300);
        Chart chart = chartShape.getChart();
        // 设置图表标题
        ChartTitle title = chart.getTitle();

        title.setText(chartVO.getTitle());
        // 设置图表数据
        chart.getSeries().clear();
        List<BarPercentStackedVO.BarPercentStackedData> dataList = chartVO.getDataList();
        List<String> series = chartVO.getSeries();
        for (BarPercentStackedVO.BarPercentStackedData barPercentStackedData : dataList) {
            //chart.getSeries().add(barPercentStackedData.getSeries(), barPercentStackedData.getCategories(), barPercentStackedData.getValues());
        }*/
        return ReplaceAction.SKIP;
    }

    /**
     * 加载统计图
     *
     * @param builder
     * @param chatType   统计图类型
     * @param title      统计图标题
     * @param categories 统计图字段
     * @param values     统计图字段数据
     */
    private static void addChart(DocumentBuilder builder, int chatType, String title, String[] series, String[] categories, double[][] values, double height, double width, Boolean dataPercent, Boolean coordinatePercent) {
        //设置首行缩进
       /* builder.getParagraphFormat().setFirstLineIndent(0);
        builder.writeln("");*/
        try {
            Shape shape = builder.insertChart(chatType, width, height);
            shape.setVerticalAlignment(VerticalAlignment.CENTER);
            shape.setHorizontalAlignment(HorizontalAlignment.CENTER);
            // 不覆盖
            shape.setAllowOverlap(false);
            Chart chart = shape.getChart();
            ChartSeriesCollection seriesCollection = chart.getSeries();
            // 清除默认
            seriesCollection.clear();

            // 显示在下面
            chart.getLegend().setPosition(LegendPosition.BOTTOM);
            // 添加数据
            ChartTitle ct = chart.getTitle();
            ct.setText(title);
            ct.setOverlay(false);
            //如果是柱形图则不显示标题
            ChartLegend cl = chart.getLegend();
            cl.setOverlay(false);
            if (coordinatePercent) {
                chart.getAxisY().getNumberFormat().setFormatCode("0.00%");
                chart.getAxisX().getNumberFormat().setFormatCode("0.00%");
            }
            Color[] customColors = new Color[]{new Color(147, 205, 221), new Color(250, 192, 144), new Color(25, 202, 173), new Color(214, 213, 183), new Color(209, 186, 116), new Color(230, 206, 172), new Color(236, 173, 158), new Color(244, 96, 108), new Color(190, 237, 199), new Color(140, 199, 181), new Color(160, 238, 225), new Color(230, 224, 236)};
            String[] categoriesNew = new String[categories.length];
            for (int i = 0; i < categories.length; i++) {
                categoriesNew[i] = "";
            }
            for (int i = 0; i < series.length; i++) {
                if (i == 0) {
                    ChartSeries chatSeries = seriesCollection.add(series[i], categories, values[i]);
                    chatSeries.getFormat().getFill().setForeColor(customColors[i % 10]);
                } else {
                    ChartSeries chatSeries = seriesCollection.add(series[i], categoriesNew, values[i]);
                    chatSeries.getFormat().getFill().setForeColor(customColors[i % 10]);
                }

            }
            Iterator<ChartSeries> iterator = seriesCollection.iterator();
            int i = 0;
            while (iterator.hasNext()) {
                ChartSeries seriesNew = iterator.next();
                //将图表中的折现设置为平滑
                seriesNew.setSmooth(true);
                // 设置数据显示
                ChartDataLabelCollection dataLabelCollection = seriesNew.getDataLabels();
                // 根据参数 showPercent 决定是否显示百分比，如果为 true，则显示百分比；否则，显示Y轴值。
                if (dataPercent) {
                    dataLabelCollection.getNumberFormat().setFormatCode("0.00%");
                }
                // 所有参数为0不展示值
                if (!allValueIsZero(values[i])) {
                    dataLabelCollection.setShowValue(true);
                }
                // 设置数据标签的分隔符为换行符，即每个标签显示在一行。
                dataLabelCollection.setSeparator("\r\n");
                dataLabelCollection.setShowLegendKey(true);   // 是否显示图例
                dataLabelCollection.setShowCategoryName(false);//是否显示系列的名称在系列旁边
                dataLabelCollection.setShowLeaderLines(false);
                dataLabelCollection.setShowSeriesName(false);//是否将图形标题显示在系列名称中
                dataLabelCollection.setShowBubbleSize(false);
                i++;
            }
            /*builder.writeln("");
            builder.getParagraphFormat().setFirstLineIndent(0);*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void createChart3(DocumentBuilder builder, String caption, String title1, String title2, String name1, String name2, String name3, String name4, double[] valueArr1, double[] valueArr2) throws Exception {
        Color[] customColors = new Color[]{new Color(147, 205, 221), new Color(250, 192, 144), new Color(25, 202, 173), new Color(214, 213, 183), new Color(209, 186, 116), new Color(230, 206, 172), new Color(236, 173, 158), new Color(244, 96, 108), new Color(190, 237, 199), new Color(140, 199, 181), new Color(160, 238, 225), new Color(230, 224, 236)};
        Shape shape = builder.insertChart(ChartType.COLUMN_STACKED, 432, 252);
        Chart chart = shape.getChart();
        chart.getTitle().setText(caption);
        ChartSeriesCollection seriesColl = chart.getSeries();
        seriesColl.clear();
        seriesColl.add(title1, new String[]{name1, name2, name3, name4}, valueArr1);
        seriesColl.add(title2, new String[]{"", "", "", ""}, valueArr2);
        Iterator<ChartSeries> iterator = seriesColl.iterator();
        int i = 0;
        while (iterator.hasNext()) {
            ChartSeries series = iterator.next();
            //将图表中的折现设置为平滑
            series.setSmooth(true);
            ChartDataLabelCollection dataLabelCollection = series.getDataLabels();
            dataLabelCollection.setShowValue(true);
            Iterator<ChartDataLabel> iterator1 = dataLabelCollection.iterator();
            while (iterator1.hasNext()) {
                ChartDataLabel chartDataLabel = iterator1.next();
                chartDataLabel.setShowValue(true);
                chartDataLabel.setShowPercentage(true);
                chartDataLabel.setShowPercentage(true);
            }
            series.getFormat().getFill().setForeColor(customColors[i % 10]);
            i++;
        }
        //数据标签显示在顶上
        chart.getLegend().setPosition(LegendPosition.TOP);
        chart.getTitle().setShow(true);
        chart.getTitle().setText(caption);
        //不覆盖 选择数据标题不覆盖在图形标题上 不然会字体重合
        chart.getTitle().setOverlay(false);
        chart.getLegend().setOverlay(false);
        builder.getParagraphFormat().setFirstLineIndent(2);
    }

    private void splitRun(Node currentNode, int position) {
        String text = currentNode.getText();
        Node newNode = currentNode.deepClone(true);
        if (text.length() >= position + this.key.length()) {
            ((Run) currentNode).setText(text.substring(position + this.key.length()));
        } else {
            int morlength = position + this.key.length() - text.length();
            ((Run) currentNode).setText("");
            Node tmpnode = currentNode;
            for (int i = 0; i < this.key.length(); i++) {
                System.out.println(i);
                tmpnode = tmpnode.getNextSibling();
                String tmptext = tmpnode.getText();
                System.out.println(tmptext);
                System.out.println(morlength);
                System.out.println("--------" + (tmptext.length() >= morlength));

                if (tmptext.length() >= morlength) {
                    ((Run) tmpnode).setText(tmptext.substring(morlength));
                    break;
                } else {
                    morlength = morlength - tmptext.length();
                    ((Run) tmpnode).setText("");
                }
            }
        }
        if (position > 0) {
            ((Run) newNode).setText(text.substring(0, position));
            currentNode.getParentNode().insertBefore(newNode, currentNode);
        }
    }

    /**
     * 判断图形（柱状图）所有值为0
     *
     * @param value
     * @return
     */
    public static boolean allValueIsZero(double[] value) {
        boolean res = true;
        for (double tmp : value) {
            if (tmp > 0) {
                res = false;
                break;
            }
        }
        return res;
    }

    public static void main(String[] args) throws Exception {
        // 创建文档对象
//        Document doc = new Document();
//        DocumentBuilder builder = new DocumentBuilder(doc);
//
//        // 统计图标题
//
//        String[] title = {"教育方式良好","教育方式基本适当","教育方式急需改善"};
//
//        // 统计图字段
//        String[] categories = {""};
//        // 统计图字段数据（二维数组支持多折线）
//        double[][] values = {
//                {2.2},  // 第一个数据系列的值
//                {3.1},
//                {3.2}// 第二个数据系列的值
//        };
//
//        addChart(builder, ChartType.COLUMN_STACKED, null, title, categories, values,215,316,true,true);
//
//        // 保存文档
//        doc.save("D://saveFile//test//StackedLineChart.docx");


        //通过Document空的构造函数，创建一个新的空的文档,如果有参数则是根据模板加载文档。
//        Document doc = new Document("D://12312.docx");
//        //动态增加内容 获取光标，这里面的`builder`相当于一个画笔，提前给他规定样式，然后他就能根据你的要求画出你想画的Word。这里的画笔使用的是就近原则，当上面没有定义了builder的时候，会使用默认的格式，当上面定义了某个格式的时候，使用最近的一个（即最后一个改变的样式）
//        DocumentBuilder builder = new DocumentBuilder(doc);
//        //将光标移动到文档末端
//        builder.moveToDocumentEnd();
//        //分页
//        builder.insertBreak(BreakType.PAGE_BREAK);
//        //换行
//        builder.insertParagraph();
//
//        //将数据转换为图表接受的格式
//        double[] thisMonths =  new double[]{78.36,98.14,56.25,68.24};
//        double[] lastMonths =  new double[]{98.51,14.74,57.25,78.24};
//        String[] names = {"三方协议","实习保险","专业匹配率","上岗率"};
//        //多维柱状图
//        createChart3(
//                builder,"备案过程数据统计","11月","12月",
//                names[0],names[1],names[2],names[3],thisMonths,lastMonths
//        );
//
//        //文件命名
//        String fileName = "D://AsposeWord1"+new SimpleDateFormat("MMddHHmmss").format(new Date())+".docx";
//        //文件保存
//        doc.save(fileName);
        Document doc = new Document();
        DocumentBuilder builder = new DocumentBuilder(doc);
        Shape shape = builder.insertChart(ChartType.LINE, 432.0, 252.0);
        Chart chart = shape.getChart();
        chart.getTitle().setText("Data Labels With Different Number Format");

//删除默认生成的系列。
        chart.getSeries().clear();

//添加带有数据和数据标签的系列。
        ChartSeries series1 = chart.getSeries().add("Aspose Series 1", new String[]{"Category 1", "Category 2", "Category 3"}, new double[]{2.5, 1.5, 3.5});

        series1.hasDataLabels(true);
        series1.getDataLabels().setShowValue(true);
        series1.getDataLabels().get(0).getNumberFormat().setFormatCode("\"$\"#,##0.00");
        series1.getDataLabels().get(1).getNumberFormat().setFormatCode("dd/mm/yyyy");
        series1.getDataLabels().get(2).getNumberFormat().setFormatCode("0.00%");

//或者将格式代码链接到源单元格。
        series1.getDataLabels().get(2).getNumberFormat().isLinkedToSource(true);
        String fileName = "D://AsposeWord1" + new SimpleDateFormat("MMddHHmmss").format(new Date()) + ".docx";
        //文件保存
        doc.save(fileName);

    }
}
